/**
 * 
 */
package edu.arizona.eller.mis.hippo.adapter.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import edu.arizona.eller.mis.hippo.adapter.ProductSearch;
import edu.arizona.eller.mis.hippo.bean.Product;
import edu.arizona.eller.mis.hippo.exception.SimpleException;
import edu.arizona.eller.mis.hippo.facade.CraigsListFacade;

/**
 * @author Blaine Boule - blaineb@email.arizona.edu
 *
 */
public class CraigsListAdapter implements ProductSearch {

	/* (non-Javadoc)
	 * @see edu.arizona.eller.mis.hippo.adapter.ProductSearch#keywordSearch(java.lang.String)
	 */
	@Override
	public List<Product> keywordSearch(String keyword) throws SimpleException {
			
		CraigsListFacade clf = new CraigsListFacade();
		Document result = clf.fullSearch(keyword);
		
		return convertToProduct(result);
	}

	/* (non-Javadoc)
	 * @see edu.arizona.eller.mis.hippo.adapter.ProductSearch#keywordSearch(java.lang.String, java.lang.String)
	 */
	@Override
	public List<Product> keywordSearch(String keyword, String condition) throws SimpleException {
		
		CraigsListFacade clf = new CraigsListFacade();
		Document result = clf.fullSearch(keyword);
		List<Product> resultList = convertToProduct(result);
		
		filterProducts(resultList, condition);
		
		return resultList;
	}

	/* (non-Javadoc)
	 * @see edu.arizona.eller.mis.hippo.adapter.ProductSearch#titleSearch(java.lang.String)
	 */
	@Override
	public List<Product> titleSearch(String keyword) throws SimpleException {
		CraigsListFacade clf = new CraigsListFacade();
		Document result = clf.titleSearch(keyword);
		
		
		return convertToProduct(result);
	}

	/* (non-Javadoc)
	 * @see edu.arizona.eller.mis.hippo.adapter.ProductSearch#titleSearch(java.lang.String, java.lang.String)
	 */
	@Override
	public List<Product> titleSearch(String keyword, String condition) throws SimpleException {
		
		CraigsListFacade clf = new CraigsListFacade();
		Document result = clf.titleSearch(keyword);
		
		List<Product> resultList = convertToProduct(result);
		
		filterProducts(resultList, condition);
		
		return resultList;
	}
	
	private List<Product> convertToProduct(Document doc) throws SimpleException{
		List<Product> products = new ArrayList<Product>();
		try {
			if (doc != null) {
				XPath xpath = XPathFactory.newInstance().newXPath();
				XPathExpression itemExpression;
				
				itemExpression = xpath.compile("//item");
				
				NodeList nodes = (NodeList) itemExpression.evaluate(doc,XPathConstants.NODESET);
				Product p;
				for (int i = 0; i < nodes.getLength(); i++) {
					p = new Product();
					Node node = nodes.item(i);
	
					p.setName((String) xpath.evaluate("title", node,XPathConstants.STRING));
					p.setDescription((String) xpath.evaluate("description", node,XPathConstants.STRING));
					String price = (String) xpath.evaluate("title", node,XPathConstants.STRING);

					p.setPrice(determinePrice(price));
					p.setUrl((String) xpath.evaluate("link", node,XPathConstants.STRING));
					products.add(p);
				}
			}
		} catch (XPathExpressionException e) {
			e.printStackTrace();
			throw new SimpleException("XPathExpression Exception durring product conversion");
		}

		return products;
	}
	
	private String determinePrice(String priceString){
		String returnPrice = "Unable to determine, please check title and/or description for price";
		if(priceString != null){
			int priceIndex = priceString.indexOf("$");
			if(priceIndex != -1){
				int endPriceIndex = priceString.indexOf(" ",priceIndex+1);
				if(endPriceIndex != -1){
					returnPrice = priceString.substring(priceIndex,endPriceIndex);
				}else{
					returnPrice = priceString.substring(priceIndex,priceString.length());
				}
			}
		}
		return returnPrice;
			
	}
	
	private void filterProducts(List<Product> listToFilter, String filterWord){
		//Remove any elements that do not contain the filter word
		if(listToFilter != null){
			Product p;
			for (Iterator<Product> it = listToFilter.iterator(); it.hasNext();){
				p = it.next();
				if(!(p.getName().toLowerCase().contains(filterWord.toLowerCase())) || !(p.getDescription().toLowerCase().contains(filterWord.toLowerCase()))){
					it.remove();
				}
			}
		}
		
	}

}
